package com.example.demo.study.lambda;

/**
 *  Function有一个参数并且返回一个结果，并附带了一些可以和其他函数组合的默认方法
 *  compose方法表示在某个方法之前执行
 * andThen方法表示在某个方法之后执行
 * 注意：compose和andThen方法调用之后都会把对象自己本身返回，这可以方便链式编程
 * default <V> Function<T,V> andThen(Function<? super R,? extends V> after) 返回一个先执行当前函数对象apply方法再执行after函数对象apply方法的函数对象。
 *
 *  default <V> Function<T,V> compose(Function<? super V,? extends T> before)返回一个先执行before函数对象apply方法再执行当前函数对象apply方法的函数对象。
 *
 *  static <T> Function<T,T> identity() 返回一个执行了apply()方法之后只会返回输入参数的函数对象。
 */
public class LambdaFunction {
    //静态内部类
    private static class Student{
        private String name;
        public Student(String name){
            this.name = name;
        }
        public String getName() {
            return name;
        }

    }
    public static void main(String[] args) {
        /*用户注册输入一个名字tom*/
        String name = "tom";

        /*使用用户的输入的名字创建一个对象*/
        Function<String, Student> f1 = (s) -> new Student(s);
        //注意上面的代码也可以写出这样，引用类中的构造器
        //Function<String, Student> f1 =Student::new;
        Student stu1 = f1.apply(name);
        System.out.println(stu1.getName());

        /*需求改变,使用name创建Student对象之前需要给name加一个前缀*/
        Function<String, String> before = (s) -> "briup_" + s;
        //表示f1调用之前先执行before对象的方法,把before对象的方法返回结果作为f1对象方法的参数
        Student stu2 = f1.compose(before).apply(name);
        System.out.println(stu2.getName());

        /*获得创建好的对象中的名字的长度*/
        Function<Student, Integer> after = (stu) -> stu.getName().length();
        //before先调用方法,结果作为参数传给f1来调用方法,结果再作为参数传给after,结果就是我们接收的数据
        int len = f1.compose(before).andThen(after).apply(name);
        System.out.println(len);
    }
}
